//=============================================================================

#include <math.h>
#include <windows.h>
#include "../inc/aCamera.h"
#include "../inc/aAux.h"

//=============================================================================

aCamera::aCamera()
{
  type = 0;
}

//=============================================================================

void aCamera::acSetCamera(const aVector& vec, const aVector& vec2, const aVector& vec3)
{
  position.x = vec.x;
  position.y = vec.y;
  position.z = vec.z;

  viewPoint.x = vec2.x;
  viewPoint.y = vec2.y;
  viewPoint.z = vec2.z;

  upVector.x = vec3.x;
  upVector.y = vec3.y;
  upVector.z = vec3.z;
}

//=============================================================================

void aCamera::acMoveCamera(float speed)
{
  aVector tmp;

  tmp.x = viewPoint.x - position.x;
  tmp.y = viewPoint.y - position.y;
  tmp.z = viewPoint.z - position.z;

  tmp = aAux::aaGetInstance().aaNormalize(tmp);

  position.x += tmp.x*speed;
  position.y += tmp.y*speed;
  position.z += tmp.z*speed;
  viewPoint.x += tmp.x*speed;
  viewPoint.y += tmp.y*speed;
  viewPoint.z += tmp.z*speed;
}

//=============================================================================

void aCamera::acMoveCamera(const aVector& vec, float speed)
{
  position.x += vec.x*speed;
  position.z += vec.z*speed;
  viewPoint.x += vec.x*speed;
  viewPoint.z += vec.z*speed;
}

//=============================================================================

void aCamera::acRotateCamera(float angle, float x, float y, float z)
{
  aVector vec, vec2;
  float mCos = cos(angle);
  float mSin = sin(angle);
  float mmCos = 1 - mCos;

  vec.x = viewPoint.x - position.x;
  vec.y = viewPoint.y - position.y;
  vec.z = viewPoint.z - position.z;

  vec2.x =  (mCos + mmCos*x*x)*vec.x;
  vec2.x += (mmCos*x*y - z*mSin)*vec.y;
  vec2.x += (mmCos*x*z + y*mSin)*vec.z;

  vec2.y =  (mmCos*x*y + z*mSin)*vec.x;
  vec2.y += (mCos + mmCos*y*y)*vec.y;
  vec2.y += (mmCos*y*z - x*mSin)*vec.z;

  vec2.z =  (mmCos*x*z - y*mSin)*vec.x;
  vec2.z += (mmCos*y*z + x*mSin)*vec.y;
  vec2.z += (mCos + mmCos*z*z)*vec.z;

  viewPoint.x = position.x + vec2.x;
  viewPoint.y = position.y + vec2.y;
  viewPoint.z = position.z + vec2.z;
}

//=============================================================================

void aCamera::acCheckMouse(int wx, int wy, int x, int y)
{
  static float currentRot = 0.0;
  aVector vec;

  if (wx == x && wy == y)
    return;

  float angleY = (float)((x - wx))/1000.0f;
  float angleZ = (float)((y - wy))/1000.0f;

  currentRot -= angleZ;
  vec = aAux::aaGetInstance().aaCrossMulty(aAux::aaGetInstance().aaSubtrack(viewPoint, position), upVector);
  vec = aAux::aaGetInstance().aaNormalize(vec);
  
  if (currentRot > 1.0)
    currentRot = 1.0;
  else
    if (currentRot < -1.0)
      currentRot = -1.0;
    else
    {
      acRotateCamera(-angleZ, vec.x, vec.y, vec.z);
      acRotateCamera(-angleY, 0.0, 1.0, 0.0);
    }
  SetCursorPos(wx, wy);
}

//=============================================================================

void aCamera::acUpdateCamera()
{
  aVector vec = aAux::aaGetInstance().aaCrossMulty(aAux::aaGetInstance().aaSubtrack(viewPoint, position), upVector);
  
  strafeVector = aAux::aaGetInstance().aaNormalize(vec);
  //acCheckMouse();
}

//=============================================================================

void aCamera::acStrafeCamera(float speed)
{
  acUpdateCamera();

  position.x += strafeVector.x*speed;
  position.z += strafeVector.z*speed;

  viewPoint.x += strafeVector.x*speed;
  viewPoint.z += strafeVector.z*speed;
}

//=============================================================================

void aCamera::acStrafeCamera(const aVector& vec, float speed)
{
  strafeVector = vec;

  position.x += strafeVector.x*speed;
  position.z += strafeVector.z*speed;

  viewPoint.x += strafeVector.x*speed;
  viewPoint.z += strafeVector.z*speed;
}

//=============================================================================

aCamera::~aCamera()
{
}

//=============================================================================
